package controller.game
{
	/**
	 * 
	 * @author Eric
	 * 构造函数中初始化牌的类型
	 * 判断牌组的类型，并比较大小
	 */	
	public class CardPattern
	{
		protected static var instance:CardPattern = null;
		//
		private var initFunc:Function = null;
		private var checkFunc:Function = null;
		private var compareFunc:Function = null;
		public static const type3and1:int = 37;
		public static const type3and2:int = 38;
		public static const type4and2:int = 39;
		static public function get Instance():CardPattern
		{
			if ( instance == null )
				instance = new CardPattern();
			return instance;
		}

		// 定义所有的卡牌的模式
		// 记录所有的牌的可能性，并进行判断
		private var pattern:Array = new Array();
		
		public function CardPattern()
		{
			initLandLord();
			for(var i:int=0;i<pattern.length;i++){
				trace(i+":"+pattern[i]);
			}
			/*for each(var tmp:Array in pattern)
			{			
		
			}*/
		}
		
		// 返回传入牌的牌型
		// 返回值是该牌型在数组中的位置，也就等于是id值
		// 如果该类型不存在，返回-1
		public function patternCheck(arr:Array):int
		{
			//给炸弹定义成index：7
			if(arr.length==2&&arr[0]==52&&arr[1]==53){
				trace("发现天王炸弹:"+arr);
				return 7;
			}
			var indexid:int= getTypeLandLord(arr);
			trace(arr.toString()+":getTypeLandLord索引值："+indexid);
			if(indexid==-1){
				indexid=getType3and4and(arr);
			 trace(arr.toString()+":getType3and4and索引值："+indexid);
			}
			return indexid;
		}

		public function getType3and4and(arr1:Array):int{
			var arr:Array= arr1.concat()		
			arr.sort(Array.NUMERIC);
			//			arr.reverse();
			trace(arr);
			for(var card:int=0;card<arr.length;card++)
			{
				arr[card]=Math.floor(arr[card]/4);
			}
			trace(arr);
			if(arr.length<4){
				return -1;
			}
			var array1:Array=new Array();
			var array2:Array=new Array();
			var array3:Array=new Array();
			var array4:Array=new Array();
			var flag:Boolean=false;
			var count:int=1;
			for(var i:int=1;i<arr.length;i++)
			{
				if(int(arr[i])!=int(arr[i-1])){
					trace(arr[i]+"不等于"+arr[i-1]);
					if(count==1){						
						array1.push(arr[i-1]);
						trace("array1.push:"+arr[i-1]);
					}else if(count==2){
						array2.push(arr[i-1]);
						//						array2.push(arr[i-1]);
						trace("array2.push:"+arr[i-1]);
					}else if(count==3){
						array3.push(arr[i-1]);
						//						array3.push(arr[i-1]);
						//						array3.push(arr[i-1]);
						trace("array3.push:"+arr[i-1]);
					}else if(count==4){
						array4.push(arr[i-1]);
						//						array4.push(arr[i-1]);
						//						array4.push(arr[i-1]);
						//						array4.push(arr[i-1]);
						trace("array4.push:"+arr[i-1]);
					}
					
					flag=true;
					count=1;
					if(i==arr.length-1){
						trace("遍历到最后")
						array1.push(arr[i]);
						trace("array1.push:"+arr[i]);
					}
					continue;
				}				
				count++;
				trace(arr[i]+"等于"+arr[i-1]+",找到相同个数："+count);
				if(i==arr.length-1){
					trace("遍历到最后")
					if(count==1){
						array1.push(arr[i]);
						trace("array1.push:"+arr[i]);
					}else if(count==2){
						array2.push(arr[i]);
						trace("array2.push:"+arr[i]);
					}
					else if(count==3){
						array3.push(arr[i]);
						trace("array3.push:"+arr[i]);
					}else if(count==4){
						array4.push(arr[i]);
						trace("array4.push:"+arr[i]);
					}
				}
				
			}
			//四带2
			if(arr.length==6){			
				if(array4.length!=1){
					return -1;
				}
			return CardPattern.type4and2;
			}else if(arr.length%4==0){
				if(array3.length<1){
					return -1;
				}
				if(!isCotinueNum(array3)){
					//这里应该考虑 333444555777，虽然段了，但是7是做单飘下去的333,444,555,666,777,888，-10~j，j-q，q-k，k-1
				   // 3,4,5-1,6,7,8-2,9-3、
				/*	var maxcount3:int=0;
					var count3:int=1;
					for(var i:int=1;i<array3.length;i++)
					{
						if(int(array3[i])!=int(array3[i-1])+1){
							if(count3>maxcount3){
								maxcount3=count3;
							}
							count3=1;
							continue;
						}						
						maxcount3++;
						if(count3>maxcount3){
							maxcount3=count3;
						}
					}*/
					trace("!isCotinueNum(array3)");
					return -1;
				}
				
				trace("isCotinueNum(array3)");
				if(array3.length==array4.length*4+array2.length*2+array1.length){
					trace("是三带1的整数个");
					return CardPattern.type3and1;
				}
				trace("不是是三带1的整数个");
				return -1;
			}
			else if(arr.length%5==0){
				if(array3.length<1){
					return -1;
				}
				if(!isCotinueNum(array3)){
					trace("!isCotinueNum(array3)");
					return -1;
				}
				trace("isCotinueNum(array3)");
				if(array3.length==array4.length*2+array2.length){
					trace("是三带2的整数个");
					return CardPattern.type3and2;
				}
				trace("不是是三带2的整数个");
				return -1;			
			}
			trace("该牌个数不对!");
			return -1;
		}
		public function isCotinueNum(arr:Array):Boolean{
			if(arr.length<1){
				return false;
			}
			if(arr.length==1){
				return true;
			}
			for(var i:int=1;i<arr.length;i++)
			{
				if(int(arr[i])!=int(arr[i-1])+1){
					return false;
				}
			}
			return true;
		}
		// 传入比较的2个数组必须是相同的类别才有效
		// 为真表示,第一个值要比第二个大,否则的话,第一个比第二个小或者相等.
		public function patternCompare(data1:Array, data2:Array):Boolean
		{
			return compareLandlord(data1, data2);
		}

		/**
		* 以下是各种牌组的具体实现，在选取时，可以自行的对牌组进行组合
		* 
		*/
		//////////////////////双扣////////////////////////////
		private function initLandLord():void
		{
			var i:int;
			// index 0-7
			for(i=0;i<8;i++)		
			{
				var ary:Array = new Array();
				for(var j:int=0;j<i+1;j++)
				{
					ary.push(0);			// 3，33，333，3333，33333，333333，3333333，33333333
				}
				pattern.push(ary);
			}
			// index 8-15
			for(i=0;i<8;i++)			// 34567, 345678,3-9,3-10,3-J,3-Q,3-K,3-A
			{
				ary = new Array();
				for(j=0;j<i+5;j++)
				{
					ary.push(j);
				}
				pattern.push(ary);
			}
			// index 16-25
			for(i=0;i<10;i++)			// 334455, 33-66,3-7,3-8,3-9,3-10,3-J,3-Q,3-K,3-A
			{
				ary = new Array();
				for(j=0;j<i+3;j++)
				{
					ary.push(j);
					ary.push(j);
				}
				pattern.push(ary);
			}
			// index 26-35
			for(i=0;i<11;i++)			// 333444555, 333-666,3-7,3-8,3-9,3-10,3-J,3-Q,3-K,3-A
			{
				ary = new Array();
				for(j=0;j<i+2;j++)
				{
					ary.push(j);
					ary.push(j);
					ary.push(j);
				}
				pattern.push(ary);
			}	
		/*	// index 36-49
			for(i=1;i<15;i++)			// 3334, 3335,3336,
			{
				ary = new Array();
				ary.push(0);
				ary.push(0);
				ary.push(0);			
				ary.push(j);	
				pattern.push(ary);
			}*/	
		}
		/**
		 * 以下是各种牌组的具体实现，在选取时，可以自行的对牌组进行组合
		 * 
		 */
		//////////////////////双扣////////////////////////////
		private function initShuangkou():void
		{
			var i:int;
			// index 0-7
			for(i=0;i<8;i++)		
			{
				var ary:Array = new Array();
				for(var j:int=0;j<i+1;j++)
				{
					ary.push(0);			// 3，33，333，3333，33333，333333，3333333，33333333
				}
				pattern.push(ary);
			}
			// index 8-15
			for(i=0;i<8;i++)			// 34567, 345678,3-9,3-10,3-J,3-Q,3-K,3-A
			{
				ary = new Array();
				for(j=0;j<i+5;j++)
				{
					ary.push(j);
				}
				pattern.push(ary);
			}
			// index 16-25
			for(i=0;i<10;i++)			// 334455, 33-66,3-7,3-8,3-9,3-10,3-J,3-Q,3-K,3-A
			{
				ary = new Array();
				for(j=0;j<i+3;j++)
				{
					ary.push(j);
					ary.push(j);
				}
				pattern.push(ary);
			}
			// index 26-35
			for(i=0;i<10;i++)			// 333444555, 333-666,3-7,3-8,3-9,3-10,3-J,3-Q,3-K,3-A
			{
				ary = new Array();
				for(j=0;j<i+2;j++)
				{
					ary.push(j);
					ary.push(j);
					ary.push(j);
				}
				pattern.push(ary);
			}	
			/*	// index 36-49
			for(i=1;i<15;i++)			// 3334, 3335,3336,
			{
			ary = new Array();
			ary.push(0);
			ary.push(0);
			ary.push(0);			
			ary.push(j);	
			pattern.push(ary);
			}*/	
		}
		private function getTypeLandLord(arr:Array):int
		{
			if(arr.length == 0)	// 没有数据的情况下
			{
				return -1;
			}
			// 新数组赋值
			var data:Array = arr.concat();
			// 对司令特别处理
			if(data[0] >= 52)	// 副司令
			{
				if(data.length == 2)
				{
					if(data[0] == data[1])
						return 1;		// 33 模式
					else
						return -1;
				}
				else if(data.length == 4)
				{
					return 7;		// 33333333 模式
				}
				else if(data.length == 1)
				{
				}
				else
					return -1;
			}
			// 所有的牌值除以4
			for(card=0;card<data.length;card++)
			{
				data[card]=int(data[card]/4);
			}
			if(data[0] != 0)
			{
				var base:int = data[0];
				for(var card:int=0;card<data.length;card++)
				{
					data[card]-=base;
				}
			}
			
			for each(var tmp:Array in pattern)
			{
				if(tmp.length != data.length)
					continue;
				var flag:Boolean = false;
				for(var m:int=0;m<tmp.length;m++)
				{
					if(tmp[m] != data[m])
					{
						flag = true;
						break;
					}
				}
				if(!flag)
				{
					// 2 和 司令不能出现在顺子或者连对中
					if(pattern.indexOf(tmp) >= 8 && arr[arr.length-1] >= 48/*方块2*/)
					{
						return -1;
					}
					else
						return pattern.indexOf(tmp);
				}
			}
			return -1;
		}
		private function getTypeShuangkou(arr:Array):int
		{
			if(arr.length == 0)	// 没有数据的情况下
			{
				return -1;
			}
			// 新数组赋值
			var data:Array = arr.concat();
			// 对司令特别处理
			if(data[0] >= 52)	// 副司令
			{
				if(data.length == 2)
				{
					if(data[0] == data[1])
						return 1;		// 33 模式
					else
						return -1;
				}
				else if(data.length == 4)
				{
					return 7;		// 33333333 模式
				}
				else if(data.length == 1)
				{
				}
				else
					return -1;
			}
			// 所有的牌值除以4
			for(card=0;card<data.length;card++)
			{
				data[card]=int(data[card]/4);
			}
			if(data[0] != 0)
			{
				var base:int = data[0];
				for(var card:int=0;card<data.length;card++)
				{
					data[card]-=base;
				}
			}
			
			for each(var tmp:Array in pattern)
			{
				if(tmp.length != data.length)
					continue;
				var flag:Boolean = false;
				for(var m:int=0;m<tmp.length;m++)
				{
					if(tmp[m] != data[m])
					{
						flag = true;
						break;
					}
				}
				if(!flag)
				{
					// 2 和 司令不能出现在顺子或者连对中
					if(pattern.indexOf(tmp) >= 8 && arr[arr.length-1] >= 48/*方块2*/)
					{
						return -1;
					}
					else
						return pattern.indexOf(tmp);
				}
			}
			return -1;
		}
		public function getFourArray(arr1:Array,array1:Array,array2:Array,array3:Array,array4:Array):void{
			var arr:Array=arr1.concat();
			arr.concat()
			arr.sort(Array.NUMERIC);			
			trace(arr);
			for(var card:int=0;card<arr.length;card++)
			{
				arr[card]=Math.floor(arr[card]/4);
			}
			trace(arr);
			array1.splice(0);
			array2.splice(0);
			array3.splice(0);
			array4.splice(0);
			var flag:Boolean=false;
			var count:int=1;
			for(var i:int=1;i<arr.length;i++)
			{
				if(int(arr[i])!=int(arr[i-1])){
					trace(arr[i]+"不等于"+arr[i-1]);
					if(count==1){						
						array1.push(arr[i-1]);
						trace("array1.push:"+arr[i-1]);
					}else if(count==2){
						array2.push(arr[i-1]);
						//						array2.push(arr[i-1]);
						trace("array2.push:"+arr[i-1]);
					}else if(count==3){
						array3.push(arr[i-1]);
						//						array3.push(arr[i-1]);
						//						array3.push(arr[i-1]);
						trace("array3.push:"+arr[i-1]);
					}else if(count==4){
						array4.push(arr[i-1]);
						//						array4.push(arr[i-1]);
						//						array4.push(arr[i-1]);
						//						array4.push(arr[i-1]);
						trace("array4.push:"+arr[i-1]);
					}
					
					flag=true;
					count=1;
					if(i==arr.length-1){
						trace("遍历到最后")
						array1.push(arr[i]);
						trace("array1.push:"+arr[i]);
					}
					continue;
				}				
				count++;
				trace(arr[i]+"等于"+arr[i-1]+",找到相同个数："+count);
				if(i==arr.length-1){
					trace("遍历到最后")
					if(count==1){
						array1.push(arr[i]);
						trace("array1.push:"+arr[i]);
					}else if(count==2){
						array2.push(arr[i]);
						trace("array2.push:"+arr[i]);
					}
					else if(count==3){
						array3.push(arr[i]);
						trace("array3.push:"+arr[i]);
					}else if(count==4){
						array4.push(arr[i]);
						trace("array4.push:"+arr[i]);
					}
				}
				
			}
		}
		private function compareLandlord(data1:Array, data2:Array):Boolean
		{
			var index1:int=patternCheck(data1);
			var index2:int=patternCheck(data2);
			//都不是炸弹比较
			if((index2<3 ||index2 >7)&&(index1 <3 || index1 >7)){
				//牌种不一样，直接不能出牌
				if(index2!=index1){
					return false;
				}
				
				if(index1==CardPattern.type3and1||index1==CardPattern.type3and2||index1==CardPattern.type4and2){
					var array11:Array=new Array();
					var array12:Array=new Array();
					var array13:Array=new Array();
					var array14:Array=new Array();
					getFourArray(data1,array11,array12,array13,array14);
					
					var array21:Array=new Array();
					var array22:Array=new Array();
					var array23:Array=new Array();
					var array24:Array=new Array();
					getFourArray(data2,array21,array22,array23,array24);
					if(index1==CardPattern.type3and1){
						if(array13.length!=array23.length){
							trace("两个飞机牌的长度不一样，自己："+array13.length+",对手："+array23.length);
							return false;
						}
						if(int(array13[0])>int(array23[0])){
							trace("type3and1:特殊牌比较，手牌"+array13[0]+"大于"+array23[0]);
							return true;
						}else{
							trace("type3and1:特殊牌比较，手牌"+array13[0]+"小于"+array23[0]);
							return false;
						}
						
					}else if(index1==CardPattern.type3and2){
						if(array13.length!=array23.length){
							trace("两个飞机牌的长度不一样，自己："+array13.length+",对手："+array23.length);
							return false;
						}
						if(int(array13[0])>int(array23[0])){							
							trace("type3and1:特殊牌比较，手牌"+array13[0]+"大于"+array23[0]);
							return true;
						}else{
							trace("type3and1:特殊牌比较，手牌"+array13[0]+"小于"+array23[0]);
							return false;
						}
						
					} else if(index1==CardPattern.type4and2){
						if(array14.length!=array24.length){
							trace("两个四带二牌的长度不一样，自己："+array14.length+",对手："+array24.length);
							return false;
						}
						if(int(array14[0])>int(array24[0])){
							trace("type4and2:特殊牌比较，手牌"+array14[0]+"大于"+array24[0]);
							return true;
						}else{
							trace("type4and2:特殊牌比较，手牌"+array14[0]+"小于"+array24[0]);
							return false;
						}
					}
				}			
			}
			// 是否是炸弹
			if(index1 >=3 && index1 <=7)
			{
				//天王最大，压倒一切炸弹
				if(data1.length==2&&data1[0]==52&&data1[1]==53){
				    trace("天王最大，压倒一切炸弹");
					return true;
				}
				//天王最大，压倒一切炸弹
				if(data2.length==2&&data2[0]==52&&data2[1]==53){
					trace("人家都是天王最大，你还能来过人家吗？");
					return false;
				}
				// 上一副牌是不是炸弹
				if(index2 >=3 && index2 <=7)
				{
					// 天王炸的处理
					// 打出的是天王炸
					if(data1.length == 4 && data1[0] >= 52)
					{
						return true;
					}
					if(data2.length == 4 && data2[0] >= 52)
					{
						// 上一副出的是天王炸
						return false;
					}
					
					if(data1.length > data2.length)
						return true;
					else if(data1.length == data2.length)
					{
						if(int(data1[0]/4) > int(data2[0]/4))
							return true;
						else
							return false;
					}
					else
						return false;
				}
				else
				{
					return true;
				}
			}
		/*	else if(index2 >=3 && index2 <=7){
				return false;
			}*/
			else
			{
				// 如果是司令
				if(data1[0] >= 52)
				{
					if(int(data1[0]) > int(data2[0]))
						return true;
					else
						return false;
				}
				else
				{
					if(int(data1[0]/4) > int(data2[0]/4))
						return true;
					else
						return false;
				}
			}
		}
		private function compareShuangkou(data1:Array, data2:Array):Boolean
		{
			// 是否是炸弹
			if(patternCheck(data1) >=3 && patternCheck(data1) <=7)
			{
				// 上一副牌是不是炸弹
				if(patternCheck(data2) >=3 && patternCheck(data2) <=7)
				{
					// 天王炸的处理
						// 打出的是天王炸
					if(data1.length == 4 && data1[0] >= 52)
					{
						return true;
					}
					if(data2.length == 4 && data2[0] >= 52)
					{
						// 上一副出的是天王炸
						return false;
					}
					
					if(data1.length > data2.length)
						return true;
					else if(data1.length == data2.length)
					{
						if(int(data1[0]/4) > int(data2[0]/4))
							return true;
						else
							return false;
					}
					else
						return false;
				}
				else
				{
					return true;
				}
			}
			else
			{
				// 如果是司令
				if(data1[0] >= 52)
				{
					if(int(data1[0]) > int(data2[0]))
						return true;
					else
						return false;
				}
				else
				{
					if(int(data1[0]/4) > int(data2[0]/4))
						return true;
					else
						return false;
				}
			}
		}
	}
}